package org.codehaus.activemq.selector;

import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import javax.jms.InvalidSelectorException;
import org.codehaus.activemq.filter.ArithmeticExpression;
import org.codehaus.activemq.filter.BooleanExpression;
import org.codehaus.activemq.filter.ComparisonExpression;
import org.codehaus.activemq.filter.ConstantExpression;
import org.codehaus.activemq.filter.Expression;
import org.codehaus.activemq.filter.ExpressionFilter;
import org.codehaus.activemq.filter.Filter;
import org.codehaus.activemq.filter.LogicExpression;
import org.codehaus.activemq.filter.PropertyExpression;
import org.codehaus.activemq.filter.UnaryExpression;

public class SelectorParser implements SelectorParserConstants {
	public SelectorParserTokenManager token_source;
	SimpleCharStream jj_input_stream;
	public Token token;
	public Token jj_nt;
	private int jj_ntk;
	private Token jj_scanpos;
	private Token jj_lastpos;
	private int jj_la;
	public boolean lookingAhead = false;
	private boolean jj_semLA;

	public SelectorParser() {
		this(new StringReader(""));
	}

	public Filter parse(String sql) throws InvalidSelectorException {
		ReInit(new StringReader(sql));
		try {
			return JmsSelector();
		} catch (TokenMgrError e) {
			throw new InvalidSelectorException(e.getMessage());
		} catch (ParseException e) {
			throw new InvalidSelectorException(e.getMessage());
		}

	}

	private BooleanExpression asBooleanExpression(Expression value) throws ParseException {
		if ((value instanceof BooleanExpression)) {
			return (BooleanExpression) value;
		}
		throw new ParseException("Expression will not result in a boolean value: " + value);
	}

	public final Filter JmsSelector() throws ParseException {
		Expression left = null;
		left = orExpression();
		if ((left instanceof BooleanExpression)) {
			return new ExpressionFilter(left);
		}

		throw new ParseException("Selector does not result in a boolean value: " + left);
	}

	public final Expression orExpression() throws ParseException {
		Expression left = andExpression();
		while (true) {
			switch (this.jj_ntk == -1 ? jj_ntk() : this.jj_ntk) {
			case 10:
				break;
			default:
				break;
			}
			jj_consume_token(10);
			Expression right = andExpression();
			left = LogicExpression.createOR(asBooleanExpression(left), asBooleanExpression(right));
			break;
		}

		return left;
	}

	public final Expression andExpression() throws ParseException {
		Expression left = equalityExpression();
		while (true) {
			switch (this.jj_ntk == -1 ? jj_ntk() : this.jj_ntk) {
			case 9:
				break;
			default:
				break;
			}
			jj_consume_token(9);
			Expression right = equalityExpression();
			left = LogicExpression.createAND(asBooleanExpression(left), asBooleanExpression(right));
			break;
		}

		return left;
	}

	public final Expression equalityExpression() throws ParseException {
		Expression left = comparisonExpression();
		while (true) {
			switch (this.jj_ntk == -1 ? jj_ntk() : this.jj_ntk) {
			case 15:
			case 24:
			case 25:
				break;
			default:
				break;
			}
			switch (this.jj_ntk == -1 ? jj_ntk() : this.jj_ntk) {
			case 24:
				jj_consume_token(24);
				Expression right = comparisonExpression();
				left = ComparisonExpression.createEqual(left, right);
				break;
			case 25:
				jj_consume_token(25);
				right = comparisonExpression();
				left = ComparisonExpression.createNotEqual(left, right);
				break;
			default:
				if (jj_2_1(2)) {
					jj_consume_token(15);
					jj_consume_token(18);
					left = ComparisonExpression.createIsNull(left);
					continue;
				}

				switch (this.jj_ntk == -1 ? jj_ntk() : this.jj_ntk) {
				case 15:
					jj_consume_token(15);
					jj_consume_token(8);
					jj_consume_token(18);
					left = ComparisonExpression.createIsNotNull(left);
					break;
				default:
					jj_consume_token(-1);
					throw new ParseException();
				}

			}

		}

		// return left;
	}

	public final Expression comparisonExpression() throws ParseException {
		Expression left = addExpression();
		while (true) {
			switch (this.jj_ntk == -1 ? jj_ntk() : this.jj_ntk) {
			case 8:
			case 11:
			case 12:
			case 14:
			case 26:
			case 27:
			case 28:
			case 29:
				break;
			case 9:
			case 10:
			case 13:
			case 15:
			case 16:
			case 17:
			case 18:
			case 19:
			case 20:
			case 21:
			case 22:
			case 23:
			case 24:
			case 25:
			default:
				break;
			}
			Expression right;
			switch (this.jj_ntk == -1 ? jj_ntk() : this.jj_ntk) {
			case 26:
				jj_consume_token(26);
				right = addExpression();
				left = ComparisonExpression.createGreaterThan(left, right);
				break;
			case 27:
				jj_consume_token(27);
				right = addExpression();
				left = ComparisonExpression.createGreaterThanEqual(left, right);
				break;
			case 28:
				jj_consume_token(28);
				right = addExpression();
				left = ComparisonExpression.createLessThan(left, right);
				break;
			case 29:
				jj_consume_token(29);
				right = addExpression();
				left = ComparisonExpression.createLessThanEqual(left, right);
				break;
			case 12:
				String u = null;
				jj_consume_token(12);
				String t = stringLitteral();
				switch (this.jj_ntk == -1 ? jj_ntk() : this.jj_ntk) {
				case 13:
					jj_consume_token(13);
					u = stringLitteral();
					break;
				}

				left = ComparisonExpression.createLike(left, t, u);
				break;
			default:
				if (jj_2_2(2)) {
					u = null;
					jj_consume_token(8);
					jj_consume_token(12);
					t = stringLitteral();
					switch (this.jj_ntk == -1 ? jj_ntk() : this.jj_ntk) {
					case 13:
						jj_consume_token(13);
						u = stringLitteral();
						break;
					}

					left = ComparisonExpression.createNotLike(left, t, u);
					continue;
				}

				switch (this.jj_ntk == -1 ? jj_ntk() : this.jj_ntk) {
				case 11:
					jj_consume_token(11);
					Expression low = addExpression();
					jj_consume_token(9);
					Expression high = addExpression();
					left = ComparisonExpression.createBetween(left, low, high);
					break;
				default:
					if (jj_2_3(2)) {
						jj_consume_token(8);
						jj_consume_token(11);
						low = addExpression();
						jj_consume_token(9);
						high = addExpression();
						left = ComparisonExpression.createNotBetween(left, low, high);
						continue;
					}

					switch (this.jj_ntk == -1 ? jj_ntk() : this.jj_ntk) {
					case 14:
						jj_consume_token(14);
						jj_consume_token(30);
						right = literal();
						ArrayList list = new ArrayList();
						list.add(right);
						while (true) {
							switch (this.jj_ntk == -1 ? jj_ntk() : this.jj_ntk) {
							case 31:
								break;
							default:
								break;
							}
							jj_consume_token(31);
							right = literal();
							list.add(right);
						}
						//jj_consume_token(32);
						//left = ComparisonExpression.createInFilter(left, list);
						//break;
					default:
						if (jj_2_4(2)) {
							jj_consume_token(8);
							jj_consume_token(14);
							jj_consume_token(30);
							right = literal();
							list = new ArrayList();
							list.add(right);
							while (true) {
								switch (this.jj_ntk == -1 ? jj_ntk() : this.jj_ntk) {
								case 31:
									break;
								default:
									break;
								}
								jj_consume_token(31);
								right = literal();
								list.add(right);
							}
							//jj_consume_token(32);
							//left = ComparisonExpression.createNotInFilter(left, list);
							//continue;
						}

						jj_consume_token(-1);
						throw new ParseException();
					}

				}

			}

		}

		//return left;
	}

	public final Expression addExpression() throws ParseException {
		Expression left = multExpr();

		while (jj_2_5(2147483647)) {
			switch (this.jj_ntk == -1 ? jj_ntk() : this.jj_ntk) {
			case 33:
				jj_consume_token(33);
				Expression right = multExpr();
				left = ArithmeticExpression.createPlus(left, right);
				break;
			case 34:
				jj_consume_token(34);
				right = multExpr();
				left = ArithmeticExpression.createMinus(left, right);
				break;
			default:
				jj_consume_token(-1);
				throw new ParseException();
			}

		}

		return left;
	}

	public final Expression multExpr() throws ParseException {
		Expression left = unaryExpr();
		while (true) {
			switch (this.jj_ntk == -1 ? jj_ntk() : this.jj_ntk) {
			case 35:
			case 36:
			case 37:
				break;
			default:
				break;
			}
			switch (this.jj_ntk == -1 ? jj_ntk() : this.jj_ntk) {
			case 35:
				jj_consume_token(35);
				Expression right = unaryExpr();
				left = ArithmeticExpression.createMultiply(left, right);
				break;
			case 36:
				jj_consume_token(36);
				right = unaryExpr();
				left = ArithmeticExpression.createDivide(left, right);
				break;
			case 37:
				jj_consume_token(37);
				right = unaryExpr();
				left = ArithmeticExpression.createMod(left, right);
				break;
			default:
				jj_consume_token(-1);
				throw new ParseException();
			}

		}

		//return left;
	}

	public final Expression unaryExpr() throws ParseException {
		Expression left = null;
		if (jj_2_6(2147483647)) {
			jj_consume_token(33);
			left = unaryExpr();
		} else {
			switch (this.jj_ntk == -1 ? jj_ntk() : this.jj_ntk) {
			case 34:
				jj_consume_token(34);
				left = unaryExpr();
				left = UnaryExpression.createNegate(left);
				break;
			case 8:
				jj_consume_token(8);
				left = unaryExpr();
				left = UnaryExpression.createNOT(asBooleanExpression(left));
				break;
			case 16:
			case 17:
			case 18:
			case 19:
			case 20:
			case 22:
			case 23:
			case 30:
				left = primaryExpr();
				break;
			case 9:
			case 10:
			case 11:
			case 12:
			case 13:
			case 14:
			case 15:
			case 21:
			case 24:
			case 25:
			case 26:
			case 27:
			case 28:
			case 29:
			case 31:
			case 32:
			case 33:
			default:
				jj_consume_token(-1);
				throw new ParseException();
			}

		}

		return left;
	}

	public final Expression primaryExpr() throws ParseException {
		Expression left = null;
		switch (this.jj_ntk == -1 ? jj_ntk() : this.jj_ntk) {
		case 16:
		case 17:
		case 18:
		case 19:
		case 20:
		case 22:
			left = literal();
			break;
		case 23:
			left = variable();
			break;
		case 30:
			jj_consume_token(30);
			left = orExpression();
			jj_consume_token(32);
			break;
		case 21:
		case 24:
		case 25:
		case 26:
		case 27:
		case 28:
		case 29:
		default:
			jj_consume_token(-1);
			throw new ParseException();
		}

		return left;
	}

	public final ConstantExpression literal() throws ParseException {
		ConstantExpression left = null;
		switch (this.jj_ntk == -1 ? jj_ntk() : this.jj_ntk) {
		case 22:
			String s = stringLitteral();
			left = new ConstantExpression(s);
			break;
		case 19:
			Token t = jj_consume_token(19);
			left = ConstantExpression.createInteger(t.image);
			break;
		case 20:
			t = jj_consume_token(20);
			left = ConstantExpression.createFloat(t.image);
			break;
		case 16:
			jj_consume_token(16);
			left = ConstantExpression.TRUE;
			break;
		case 17:
			jj_consume_token(17);
			left = ConstantExpression.FALSE;
			break;
		case 18:
			jj_consume_token(18);
			left = ConstantExpression.NULL;
			break;
		case 21:
		default:
			jj_consume_token(-1);
			throw new ParseException();
		}

		return left;
	}

	public final String stringLitteral() throws ParseException {
		StringBuffer rc = new StringBuffer();
		boolean first = true;
		Token t = jj_consume_token(22);

		String image = t.image;
		for (int i = 1; i < image.length() - 1; i++) {
			char c = image.charAt(i);
			if (c == '\'') {
				i++;
			}
			rc.append(c);
		}

		return rc.toString();
	}

	public final PropertyExpression variable() throws ParseException {
		PropertyExpression left = null;
		Token t = jj_consume_token(23);
		left = new PropertyExpression(t.image);

		return left;
	}

	private final boolean jj_2_1(int xla) {
		this.jj_la = xla;
		this.jj_lastpos = (this.jj_scanpos = this.token);
		return !jj_3_1();
	}

	private final boolean jj_2_2(int xla) {
		this.jj_la = xla;
		this.jj_lastpos = (this.jj_scanpos = this.token);
		return !jj_3_2();
	}

	private final boolean jj_2_3(int xla) {
		this.jj_la = xla;
		this.jj_lastpos = (this.jj_scanpos = this.token);
		return !jj_3_3();
	}

	private final boolean jj_2_4(int xla) {
		this.jj_la = xla;
		this.jj_lastpos = (this.jj_scanpos = this.token);
		return !jj_3_4();
	}

	private final boolean jj_2_5(int xla) {
		this.jj_la = xla;
		this.jj_lastpos = (this.jj_scanpos = this.token);
		return !jj_3_5();
	}

	private final boolean jj_2_6(int xla) {
		this.jj_la = xla;
		this.jj_lastpos = (this.jj_scanpos = this.token);
		return !jj_3_6();
	}

	private final boolean jj_3R_54() {
		if (jj_scan_token(33)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_3R_11()) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3R_49() {
		if (jj_scan_token(28)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_3R_41()) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3R_28() {
		if (jj_3R_36()) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3R_59() {
		if (jj_scan_token(31)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_3R_25()) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3R_46() {
		Token xsp = this.jj_scanpos;
		if (jj_3R_54()) {
			this.jj_scanpos = xsp;
			if (jj_3R_55()) {
				return true;
			}
			if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
				return false;
			}
		} else if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		return false;
	}

	private final boolean jj_3R_35() {
		if (jj_scan_token(10)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_3R_34()) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3R_48() {
		if (jj_scan_token(27)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_3R_41()) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3R_25() {
		Token xsp = this.jj_scanpos;
		if (jj_3R_28()) {
			this.jj_scanpos = xsp;
			if (jj_3R_29()) {
				this.jj_scanpos = xsp;
				if (jj_3R_30()) {
					this.jj_scanpos = xsp;
					if (jj_3R_31()) {
						this.jj_scanpos = xsp;
						if (jj_3R_32()) {
							this.jj_scanpos = xsp;
							if (jj_3R_33()) {
								return true;
							}
							if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
								return false;
							}
						} else if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
							return false;
						}
					} else if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
						return false;
					}
				} else if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
					return false;
				}
			} else if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
				return false;
			}
		} else if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		return false;
	}

	private final boolean jj_3R_47() {
		if (jj_scan_token(26)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_3R_41()) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3R_42() {
		Token xsp = this.jj_scanpos;
		if (jj_3R_47()) {
			this.jj_scanpos = xsp;
			if (jj_3R_48()) {
				this.jj_scanpos = xsp;
				if (jj_3R_49()) {
					this.jj_scanpos = xsp;
					if (jj_3R_50()) {
						this.jj_scanpos = xsp;
						if (jj_3R_51()) {
							this.jj_scanpos = xsp;
							if (jj_3_2()) {
								this.jj_scanpos = xsp;
								if (jj_3R_52()) {
									this.jj_scanpos = xsp;
									if (jj_3_3()) {
										this.jj_scanpos = xsp;
										if (jj_3R_53()) {
											this.jj_scanpos = xsp;
											if (jj_3_4()) {
												return true;
											}
											if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
												return false;
											}
										} else if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
											return false;
										}
									} else if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
										return false;
									}
								} else if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
									return false;
								}
							} else if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
								return false;
							}
						} else if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
							return false;
						}
					} else if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
						return false;
					}
				} else if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
					return false;
				}
			} else if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
				return false;
			}
		} else if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		return false;
	}

	private final boolean jj_3R_41() {
		if (jj_3R_11()) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		while (true) {
			Token xsp = this.jj_scanpos;
			if (jj_3R_46()) {
				this.jj_scanpos = xsp;
			} else if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
				return false;
			}
		}
		//return false;
	}

	private final boolean jj_3R_27() {
		if (jj_3R_34()) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		while (true) {
			Token xsp = this.jj_scanpos;
			if (jj_3R_35()) {
				this.jj_scanpos = xsp;
			} else if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
				return false;
			}
		}
		//return false;
	}

	private final boolean jj_3R_24() {
		if (jj_scan_token(30)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_3R_27()) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_scan_token(32)) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3R_23() {
		if (jj_3R_26()) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3R_22() {
		if (jj_3R_25()) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3R_58() {
		if (jj_scan_token(31)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_3R_25()) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3R_26() {
		if (jj_scan_token(23)) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3R_39() {
		if (jj_3R_41()) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		while (true) {
			Token xsp = this.jj_scanpos;
			if (jj_3R_42()) {
				this.jj_scanpos = xsp;
			} else if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
				return false;
			}
		}
		//return false;
	}

	private final boolean jj_3R_21() {
		Token xsp = this.jj_scanpos;
		if (jj_3R_22()) {
			this.jj_scanpos = xsp;
			if (jj_3R_23()) {
				this.jj_scanpos = xsp;
				if (jj_3R_24()) {
					return true;
				}
				if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
					return false;
				}
			} else if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
				return false;
			}
		} else if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		return false;
	}

	private final boolean jj_3R_57() {
		if (jj_scan_token(13)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_3R_36()) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3_4() {
		if (jj_scan_token(8)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_scan_token(14)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_scan_token(30)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_3R_25()) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		while (true) {
			Token xsp = this.jj_scanpos;
			if (jj_3R_59()) {
				this.jj_scanpos = xsp;
			} else if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
				return false;
			}
		}
		//if (jj_scan_token(32)) {
			//return true;
		//}

		//return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3_6() {
		if (jj_scan_token(33)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_3R_12()) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3R_17() {
		if (jj_3R_21()) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3R_16() {
		if (jj_scan_token(8)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_3R_12()) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3R_53() {
		if (jj_scan_token(14)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_scan_token(30)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_3R_25()) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		while (true) {
			Token xsp = this.jj_scanpos;
			if (jj_3R_58()) {
				this.jj_scanpos = xsp;
			} else if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
				return false;
			}
		}
//		if (jj_scan_token(32)) {
//			return true;
//		}

		//return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3R_45() {
		if (jj_scan_token(15)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_scan_token(8)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_scan_token(18)) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3R_14() {
		if (jj_scan_token(33)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_3R_12()) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3R_15() {
		if (jj_scan_token(34)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_3R_12()) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3R_36() {
		if (jj_scan_token(22)) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3_1() {
		if (jj_scan_token(15)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_scan_token(18)) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3R_12() {
		Token xsp = this.jj_scanpos;
		if (jj_3R_14()) {
			this.jj_scanpos = xsp;
			if (jj_3R_15()) {
				this.jj_scanpos = xsp;
				if (jj_3R_16()) {
					this.jj_scanpos = xsp;
					if (jj_3R_17()) {
						return true;
					}
					if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
						return false;
					}
				} else if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
					return false;
				}
			} else if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
				return false;
			}
		} else if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		return false;
	}

	private final boolean jj_3R_44() {
		if (jj_scan_token(25)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_3R_39()) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3_3() {
		if (jj_scan_token(8)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_scan_token(11)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_3R_41()) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_scan_token(9)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_3R_41()) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3R_43() {
		if (jj_scan_token(24)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_3R_39()) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3R_40() {
		Token xsp = this.jj_scanpos;
		if (jj_3R_43()) {
			this.jj_scanpos = xsp;
			if (jj_3R_44()) {
				this.jj_scanpos = xsp;
				if (jj_3_1()) {
					this.jj_scanpos = xsp;
					if (jj_3R_45()) {
						return true;
					}
					if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
						return false;
					}
				} else if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
					return false;
				}
			} else if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
				return false;
			}
		} else if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		return false;
	}

	private final boolean jj_3R_52() {
		if (jj_scan_token(11)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_3R_41()) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_scan_token(9)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_3R_41()) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3R_33() {
		if (jj_scan_token(18)) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3R_56() {
		if (jj_scan_token(13)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_3R_36()) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3R_20() {
		if (jj_scan_token(37)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_3R_12()) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3R_32() {
		if (jj_scan_token(17)) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3R_37() {
		if (jj_3R_39()) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		while (true) {
			Token xsp = this.jj_scanpos;
			if (jj_3R_40()) {
				this.jj_scanpos = xsp;
			} else if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
				return false;
			}
		}
		//return false;
	}

	private final boolean jj_3_2() {
		if (jj_scan_token(8)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_scan_token(12)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_3R_36()) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}

		Token xsp = this.jj_scanpos;
		if (jj_3R_57()) {
			this.jj_scanpos = xsp;
		} else if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		return false;
	}

	private final boolean jj_3R_51() {
		if (jj_scan_token(12)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_3R_36()) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}

		Token xsp = this.jj_scanpos;
		if (jj_3R_56()) {
			this.jj_scanpos = xsp;
		} else if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		return false;
	}

	private final boolean jj_3R_19() {
		if (jj_scan_token(36)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_3R_12()) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3R_31() {
		if (jj_scan_token(16)) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3R_18() {
		if (jj_scan_token(35)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_3R_12()) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3R_13() {
		Token xsp = this.jj_scanpos;
		if (jj_3R_18()) {
			this.jj_scanpos = xsp;
			if (jj_3R_19()) {
				this.jj_scanpos = xsp;
				if (jj_3R_20()) {
					return true;
				}
				if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
					return false;
				}
			} else if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
				return false;
			}
		} else if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		return false;
	}

	private final boolean jj_3R_38() {
		if (jj_scan_token(9)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_3R_37()) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3R_30() {
		if (jj_scan_token(20)) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3R_11() {
		if (jj_3R_12()) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		while (true) {
			Token xsp = this.jj_scanpos;
			if (jj_3R_13()) {
				this.jj_scanpos = xsp;
			} else if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
				return false;
			}
		}
		//return false;
	}

	private final boolean jj_3R_10() {
		if (jj_scan_token(34)) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3R_9() {
		if (jj_scan_token(33)) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3R_55() {
		if (jj_scan_token(34)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_3R_11()) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3R_34() {
		if (jj_3R_37()) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		while (true) {
			Token xsp = this.jj_scanpos;
			if (jj_3R_38()) {
				this.jj_scanpos = xsp;
			} else if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
				return false;
			}
		}
		//return false;
	}

	private final boolean jj_3_5() {
		Token xsp = this.jj_scanpos;
		if (jj_3R_9()) {
			this.jj_scanpos = xsp;
			if (jj_3R_10()) {
				return true;
			}
			if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
				return false;
			}
		} else if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_3R_11()) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3R_29() {
		if (jj_scan_token(19)) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	private final boolean jj_3R_50() {
		if (jj_scan_token(29)) {
			return true;
		}
		if ((this.jj_la == 0) && (this.jj_scanpos == this.jj_lastpos)) {
			return false;
		}
		if (jj_3R_41()) {
			return true;
		}

		return (this.jj_la != 0) || (this.jj_scanpos != this.jj_lastpos);
	}

	public SelectorParser(InputStream stream) {
		this.jj_input_stream = new SimpleCharStream(stream, 1, 1);
		this.token_source = new SelectorParserTokenManager(this.jj_input_stream);
		this.token = new Token();
		this.jj_ntk = -1;
	}

	public void ReInit(InputStream stream) {
		this.jj_input_stream.ReInit(stream, 1, 1);
		this.token_source.ReInit(this.jj_input_stream);
		this.token = new Token();
		this.jj_ntk = -1;
	}

	public SelectorParser(Reader stream) {
		this.jj_input_stream = new SimpleCharStream(stream, 1, 1);
		this.token_source = new SelectorParserTokenManager(this.jj_input_stream);
		this.token = new Token();
		this.jj_ntk = -1;
	}

	public void ReInit(Reader stream) {
		this.jj_input_stream.ReInit(stream, 1, 1);
		this.token_source.ReInit(this.jj_input_stream);
		this.token = new Token();
		this.jj_ntk = -1;
	}

	public SelectorParser(SelectorParserTokenManager tm) {
		this.token_source = tm;
		this.token = new Token();
		this.jj_ntk = -1;
	}

	public void ReInit(SelectorParserTokenManager tm) {
		this.token_source = tm;
		this.token = new Token();
		this.jj_ntk = -1;
	}

	private final Token jj_consume_token(int kind) throws ParseException {
		Token oldToken;
		if ((oldToken = this.token).next != null) {
			this.token = this.token.next;
		} else {
			this.token = (this.token.next = this.token_source.getNextToken());
		}
		this.jj_ntk = -1;
		if (this.token.kind == kind) {
			return this.token;
		}
		this.token = oldToken;
		throw generateParseException();
	}

	private final boolean jj_scan_token(int kind) {
		if (this.jj_scanpos == this.jj_lastpos) {
			this.jj_la -= 1;
			if (this.jj_scanpos.next == null) {
				this.jj_lastpos = (this.jj_scanpos = this.jj_scanpos.next = this.token_source.getNextToken());
			} else
				this.jj_lastpos = (this.jj_scanpos = this.jj_scanpos.next);
		} else {
			this.jj_scanpos = this.jj_scanpos.next;
		}
		return this.jj_scanpos.kind != kind;
	}

	public final Token getNextToken() {
		if (this.token.next != null) {
			this.token = this.token.next;
		} else {
			this.token = (this.token.next = this.token_source.getNextToken());
		}
		this.jj_ntk = -1;
		return this.token;
	}

	public final Token getToken(int index) {
		Token t = this.lookingAhead ? this.jj_scanpos : this.token;
		for (int i = 0; i < index; i++) {
			if (t.next != null) {
				t = t.next;
			} else {
				t = t.next = this.token_source.getNextToken();
			}
		}
		return t;
	}

	private final int jj_ntk() {
		if ((this.jj_nt = this.token.next) == null) {
			return this.jj_ntk = (this.token.next = this.token_source.getNextToken()).kind;
		}

		return this.jj_ntk = this.jj_nt.kind;
	}

	public final ParseException generateParseException() {
		Token errortok = this.token.next;
		int line = errortok.beginLine;
		int column = errortok.beginColumn;
		String mess = errortok.kind == 0 ? tokenImage[0] : errortok.image;
		return new ParseException("Parse error at line " + line + ", column " + column + ".  Encountered: " + mess);
	}

	public final void enable_tracing() {
	}

	public final void disable_tracing() {
	}
}